# Config file for Theia - Find Theia & dependencies.
#
# This file is used by CMake when FIND_PACKAGE( Theia ) is invoked (and
# the directory containing this file is present in CMAKE_MODULE_PATH).
#
# This module defines the following variables:
#
# Theia_FOUND / THEIA_FOUND: True iff Theia has been successfully found. Both
#                            variables are set as although FindPackage() only
#                            references Theia_FOUND in Config mode, given the
#                            conventions for <package>_FOUND when FindPackage()
#                            is called in Module mode, users could reasonably
#                            expect to use THEIA_FOUND instead.
# THEIA_VERSION: Version of Theia found.
# THEIA_INCLUDE_DIRS: Include directories for Theia and the dependencies which
#                     appear in the Theia public API and are thus required to
#                     use Theia.
# THEIA_LIBRARIES: Libraries for Theia and all dependencies against which Theia
#                  was compiled. This will not include any optional dependencies
#                  that were disabled when Theia was compiled.
#
# The following variables are also defined for legacy compatibility only.
# Any new code should not use them as they do not conform to the standard CMake
# FindPackage naming conventions.
#
# THEIA_INCLUDES = ${THEIA_INCLUDE_DIRS}.

# Called if we failed to find Theia or any of it's required dependencies,
# unsets all public (designed to be used externally) variables and reports
# error message at priority depending upon [REQUIRED/QUIET/<NONE>] argument.
macro(THEIA_REPORT_NOT_FOUND REASON_MSG)
  # FindPackage() only references Theia_FOUND, and requires it to be explicitly
  # set FALSE to denote not found (not merely undefined).
  set(Theia_FOUND FALSE)
  set(THEIA_FOUND FALSE)
  unset(THEIA_INCLUDE_DIRS)
  unset(THEIA_LIBRARIES)

  # Reset the CMake module path to its state when this script was called.
  set(CMAKE_MODULE_PATH ${THEIA_CALLERS_CMAKE_MODULE_PATH})

  # Note <package>_FIND_[REQUIRED/QUIETLY] variables defined by FindPackage()
  # use the camelcase library name, not uppercase.
  if (Theia_FIND_QUIETLY)
    message(STATUS "Failed to find Theia - " ${REASON_MSG} ${ARGN})
  else (Theia_FIND_REQUIRED)
    message(FATAL_ERROR "Failed to find Theia - " ${REASON_MSG} ${ARGN})
  else()
    # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error
    # that prevents generation, but continues configuration.
    message(SEND_ERROR "Failed to find Theia - " ${REASON_MSG} ${ARGN})
  endif ()
  return()
endmacro(THEIA_REPORT_NOT_FOUND)

# Get the (current, i.e. installed) directory containing this file.
get_filename_component(THEIA_CURRENT_CONFIG_INSTALL_DIR
  "${CMAKE_CURRENT_LIST_FILE}" PATH)

# Record the state of the CMake module path when this script was called so
# that we can ensure that we leave it in the same state on exit as it was
# on entry, but modify it locally.
set(THEIA_CALLERS_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
# Reset CMake module path to the installation directory of this script,
# thus we will use the FindPackage() scripts shipped with Theia to find
# Theia' dependencies, even if the user has equivalently named FindPackage()
# scripts in their project.
set(CMAKE_MODULE_PATH ${THEIA_CURRENT_CONFIG_INSTALL_DIR})

# Build the absolute root install directory as a relative path (determined when
# Theia was configured & built) from the current install directory for this
# this file.  This allows for the install tree to be relocated, after Theia was
# built, outside of CMake.
get_filename_component(CURRENT_ROOT_INSTALL_DIR
  ${THEIA_CURRENT_CONFIG_INSTALL_DIR}/@INSTALL_ROOT_REL_CONFIG_INSTALL_DIR@ ABSOLUTE)
if (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})
  theia_report_not_found(
    "Theia install root: ${CURRENT_ROOT_INSTALL_DIR}, "
    "determined from relative path from TheiaConfg.cmake install location: "
    "${THEIA_CURRENT_CONFIG_INSTALL_DIR}, does not exist. Either the install "
    "directory was deleted, or the install tree was only partially relocated "
    "outside of CMake after Theia was built.")
endif (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR})

# Set the version.
set(THEIA_VERSION @THEIA_VERSION@ )

# Set the include directories for Theia (itself).
set(THEIA_INCLUDE_DIR "${CURRENT_ROOT_INSTALL_DIR}/include")
if (NOT EXISTS ${THEIA_INCLUDE_DIR}/theia/theia.h)
  theia_report_not_found(
    "Theia install root: ${CURRENT_ROOT_INSTALL_DIR}, "
    "determined from relative path from TheiaConfg.cmake install location: "
    "${THEIA_CURRENT_CONFIG_INSTALL_DIR}, does not contain Theia headers. "
    "Either the install directory was deleted, or the install tree was only "
    "partially relocated outside of CMake after Theia was built.")
endif (NOT EXISTS ${THEIA_INCLUDE_DIR}/theia/theia.h)

# Append the include directories for all (potentially optional) dependencies
# with which Theia was compiled, the libraries themselves come in via
# TheiaTargets-<release/debug>.cmake as link libraries for Theia target.
set(THEIA_INCLUDE_DIRS ${THEIA_INCLUDE_DIR})

# Eigen.
# Flag set during configuration and build of Theia.
set(THEIA_EIGEN_VERSION @EIGEN_VERSION@)
# Append the locations of Eigen when Theia was built to the search path hints.
list(APPEND EIGEN_INCLUDE_DIR_HINTS @EIGEN_INCLUDE_DIR@)
# Search quietly s/t we control the timing of the error message if not found.
find_package(Eigen ${THEIA_EIGEN_VERSION} EXACT QUIET)
if (EIGEN_FOUND)
  message(STATUS "Found required Theia dependency: "
    "Eigen version ${THEIA_EIGEN_VERSION} in ${EIGEN_INCLUDE_DIRS}")
else (EIGEN_FOUND)
  theia_report_not_found("Missing required Theia "
    "dependency: Eigen version ${THEIA_EIGEN_VERSION}, please set "
    "EIGEN_INCLUDE_DIR.")
endif (EIGEN_FOUND)
list(APPEND THEIA_INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS})

# Ceres.
# Append the locations of ceres when Theia was built to the search path hints.
list(APPEND CERES_INCLUDE_DIR_HINTS @CERES_INCLUDE_DIR@)
get_filename_component(THEIA_BUILD_CERES_LIBRARY_DIR @CERES_LIBRARIES@ PATH)
list(APPEND CERES_LIBRARY_DIR_HINTS ${THEIA_BUILD_CERES_LIBRARY_DIR})
# Search quietly s/t we control the timing of the error message if not found.
find_package(Ceres QUIET)
if (CERES_FOUND)
  message(STATUS "Found required Theia dependency: "
    "Ceres in ${CERES_INCLUDE_DIRS}")
else (CERES_FOUND)
  theia_report_not_found("Missing required Theia "
    "dependency: Ceres, please set CERES_INCLUDE_DIR.")
endif (CERES_FOUND)
list(APPEND THEIA_INCLUDE_DIRS ${CERES_INCLUDE_DIRS})

# Glog.
# Append the locations of glog when Theia was built to the search path hints.
list(APPEND GLOG_INCLUDE_DIR_HINTS @GLOG_INCLUDE_DIR@)
get_filename_component(THEIA_BUILD_GLOG_LIBRARY_DIR @GLOG_LIBRARY@ PATH)
list(APPEND GLOG_LIBRARY_DIR_HINTS ${THEIA_BUILD_GLOG_LIBRARY_DIR})
# Search quietly s/t we control the timing of the error message if not found.
find_package(Glog QUIET)
if (GLOG_FOUND)
  message(STATUS "Found required Theia dependency: "
    "Glog in ${GLOG_INCLUDE_DIRS}")
else (GLOG_FOUND)
  theia_report_not_found("Missing required Theia "
    "dependency: Glog, please set GLOG_INCLUDE_DIR.")
endif (GLOG_FOUND)
list(APPEND THEIA_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS})

# GFlags. The namespace patch is borrow from Ceres Solver (see license in
# FindGflags.cmake)
find_package(Gflags QUIET)
if (GFLAGS_FOUND)
  message(STATUS "Found required Theia dependency: Google Flags in "
    "${GFLAGS_INCLUDE_DIRS} in namespace: ${GFLAGS_NAMESPACE}")
  add_definitions(-DTHEIA_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
else (GFLAGS_FOUND)
  theia_report_not_found("Missing required Theia dependency: Google Flags, please set "
    "GFLAGS_INCLUDE_DIR.")
endif (GFLAGS_FOUND)
list(APPEND THEIA_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIRS})

# OpenImageIO
find_package(OpenImageIO QUIET)
if (OPENIMAGEIO_FOUND)
  message(STATUS "Found Theia dependency: OpenImageIO in ${OPENIMAGEIO_INCLUDE_DIRS}")
else (OPENIMAGEIO_FOUND)
  theia_report_not_found("Missing required Theia dependency: OpenImageIO. Please set "
    "OPENIMAGEIO_INCLUDE_DIR & OPENIMAGEIO_LIBRARY")
endif (OPENIMAGEIO_FOUND)
list(APPEND THEIA_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIRS})

find_package(RocksDB)
if (ROCKSDB_FOUND)
  message(STATUS "Found RocksDB: ${ROCKSDB_INCLUDE_DIRS}")
else (ROCKSDB_FOUND)
theia_report_not_found("Missing required Theia dependence: RocksDB. Please "
    "set ROCKSDB_INCLUDE_DIR & ROCKSDB_LIBRARY.")
endif (ROCKSDB_FOUND)
list(APPEND THEIA_INCLUDE_DIRS ${ROCKSDB_INCLUDE_DIRS})

find_package(SuiteSparse QUIET)
if (SUITESPARSE_FOUND)
  # On Ubuntu the system install of SuiteSparse (v3.4.0) up to at least
  # Ubuntu 13.10 cannot be used to link shared libraries.
  if (BUILD_SHARED_LIBS AND
      SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
    theia_report_not_found("You are attempting to build Theia as a shared "
      "library on Ubuntu using a system package install of SuiteSparse "
      "3.4.0. This package is broken and does not support the "
      "construction of shared libraries (you can still build Theia as "
      "a static library).  If you wish to build a shared version of Theia "
      "you should uninstall the system install of SuiteSparse "
      "(libsuitesparse-dev) and perform a source install of SuiteSparse "
      "(we recommend that you use the latest version), "
      "see http://theia-solver.org/building.html for more information.")
  endif (BUILD_SHARED_LIBS AND
    SUITESPARSE_IS_BROKEN_SHARED_LINKING_UBUNTU_SYSTEM_VERSION)
  message("-- Found SuiteSparse ${SUITESPARSE_VERSION}")
  add_definitions(-DTHEIA_SUITESPARSE_VERSION="${SUITESPARSE_VERSION}")
else (SUITESPARSE_FOUND)
  # Disable use of SuiteSparse if it cannot be found and continue.
  theia_report_not_found("Can't find SuiteSparse. This library is required "
    "for bundle adjustment and for solving convex optimization problems. "
    "Please set SUITESPARSE_INCLUDE_DIR & SUITESPARSE_LIBRARY")
endif (SUITESPARSE_FOUND)
list(APPEND THEIA_INCLUDE_DIRS ${SUITESPARSE_INCLUDE_DIRS})

# Import exported Theia targets.
if (NOT TARGET theia AND NOT Theia_BINARY_DIR)
  include(${THEIA_CURRENT_CONFIG_INSTALL_DIR}/TheiaTargets.cmake)
endif (NOT TARGET theia AND NOT Theia_BINARY_DIR)
# Set the expected XX_LIBRARIES variable for FindPackage().
set(THEIA_LIBRARIES theia)

# Add the libraries included with the distribution.
set(THEIA_INTERNAL_LIB_PREFIX ${THEIA_INCLUDE_DIR}/theia/libraries)
set(THEIA_INTERNAL_LIBS_INCLUDES
  ${THEIA_INTERNAL_LIB_PREFIX}
  ${THEIA_INTERNAL_LIB_PREFIX}/akaze
  ${THEIA_INTERNAL_LIB_PREFIX}/cereal
  ${THEIA_INTERNAL_LIB_PREFIX}/cereal/include
  ${THEIA_INTERNAL_LIB_PREFIX}/flann
  ${THEIA_INTERNAL_LIB_PREFIX}/gtest
  ${THEIA_INTERNAL_LIB_PREFIX}/gtest/include
  ${THEIA_INTERNAL_LIB_PREFIX}/optimo
  ${THEIA_INTERNAL_LIB_PREFIX}/spectra
  ${THEIA_INTERNAL_LIB_PREFIX}/statx
  ${THEIA_INTERNAL_LIB_PREFIX}/stlplus3
  ${THEIA_INTERNAL_LIB_PREFIX}/vlfeat
  ${THEIA_INTERNAL_LIB_PREFIX}/visual_sfm)

list(APPEND THEIA_INCLUDE_DIRS ${THEIA_INTERNAL_LIBS_INCLUDES})

# Set legacy include directories variable for backwards compatibility.
set(THEIA_INCLUDES ${THEIA_INCLUDE_DIRS})

# Reset CMake module path to its state when this script was called.
set(CMAKE_MODULE_PATH ${THEIA_CALLERS_CMAKE_MODULE_PATH})

# As we use THEIA_REPORT_NOT_FOUND() to abort, if we reach this point we have
# found Theia and all required dependencies.
message(STATUS "Found Theia version: ${THEIA_VERSION} "
    "installed in: ${CURRENT_ROOT_INSTALL_DIR}")
# Set THEIA_FOUND to be equivalent to Theia_FOUND, which is set to TRUE by
# FindPackage() if this file is found and run, and after which Theia_FOUND
# is not (explicitly, i.e. undefined does not count) set to FALSE.
set(THEIA_FOUND TRUE)
